package com.game.doudizhu.core;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class AIModelPersistence {
    private static final Logger logger = LoggerFactory.getLogger(AIModelPersistence.class);
    private static final String MODEL_DIR = "ai_model";
    private static final String STRATEGY_WEIGHTS_FILE = "strategy_weights.json";
    private static final String CARD_PATTERNS_FILE = "card_patterns.json";
    private static final String BID_PATTERNS_FILE = "bid_patterns.json";
    
    static {
        try {
            Files.createDirectories(Paths.get(MODEL_DIR));
        } catch (IOException e) {
            logger.error("创建模型目录失败", e);
        }
    }
    
    public static class AIModel {
        public Map<String, Double> strategyWeights = new HashMap<>();
        public Map<String, Double> averageRemainingCards = new HashMap<>();
        public Map<String, Double> bidPatterns = new HashMap<>();
        
        // 用于记录叫分决策的成功率
        public Map<Integer, Integer> bidSuccesses = new HashMap<>();
        public Map<Integer, Integer> bidFailures = new HashMap<>();

        private AIModel() {

        }
    }
    
    public static void saveModel(AIModel model) {
        ObjectMapper mapper = new ObjectMapper();
        ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
        
        try {
            // 保存策略权重
            writer.writeValue(new File(MODEL_DIR + "/" + STRATEGY_WEIGHTS_FILE), 
                            new HashMap<>(model.strategyWeights));
            
            // 保存出牌模式
            writer.writeValue(new File(MODEL_DIR + "/" + CARD_PATTERNS_FILE), 
                            new HashMap<>(model.averageRemainingCards));
            
            // 保存叫分模式
            Map<String, Object> bidData = new HashMap<>();
            bidData.put("patterns", model.bidPatterns);
            bidData.put("successes", model.bidSuccesses);
            bidData.put("failures", model.bidFailures);
            writer.writeValue(new File(MODEL_DIR + "/" + BID_PATTERNS_FILE), bidData);
            
            logger.info("AI模型保存成功");
        } catch (IOException e) {
            logger.error("保存AI模型失败", e);
        }
    }

    private static AIModel aiModel;
    static {
        initAIModel();
    }
    public synchronized static AIModel loadModel() {
        if (aiModel == null) {
            initAIModel();
        }
        return aiModel;
    }

    private static void initAIModel() {
        aiModel = new AIModel();
        ObjectMapper mapper = new ObjectMapper();

        try {
            // 加载策略权重
            File strategyFile = new File(MODEL_DIR + "/" + STRATEGY_WEIGHTS_FILE);
            if (strategyFile.exists()) {
                aiModel.strategyWeights = mapper.readValue(strategyFile,
                        mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Double.class));
            }
            if (aiModel.strategyWeights.isEmpty()) {
                initializeBaseStrategies();
            }

            // 加载出牌模式
            File patternFile = new File(MODEL_DIR + "/" + CARD_PATTERNS_FILE);
            if (patternFile.exists()) {
                aiModel.averageRemainingCards = mapper.readValue(patternFile,
                        mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Double.class));
            }

            // 加载叫分模式
            File bidFile = new File(MODEL_DIR + "/" + BID_PATTERNS_FILE);
            if (bidFile.exists()) {
                Map<String, Object> bidData = mapper.readValue(bidFile, Map.class);
                aiModel.bidPatterns = (Map<String, Double>) bidData.get("patterns");
                aiModel.bidSuccesses = (Map<Integer, Integer>) bidData.get("successes");
                aiModel.bidFailures = (Map<Integer, Integer>) bidData.get("failures");
            }
            logger.info("AI模型加载成功");
        } catch (IOException e) {
            aiModel = null;
            logger.error("加载AI模型失败", e);
        }
    }

    private static void initializeBaseStrategies() {
        logger.info("初始化基础策略权重...");

        AIModelPersistence.AIModel model = new AIModelPersistence.AIModel();

        // 初始化地主策略
        model.strategyWeights.put("LANDLORD_ROCKET", 1.5);
        model.strategyWeights.put("LANDLORD_BOMB", 1.4);
        model.strategyWeights.put("LANDLORD_STRAIGHT", 1.2);
        model.strategyWeights.put("LANDLORD_STRAIGHT_PAIR", 1.2);
        model.strategyWeights.put("LANDLORD_AIRPLANE", 1.3);
        model.strategyWeights.put("LANDLORD_TRIPLE_WITH_ONE", 1.1);
        model.strategyWeights.put("LANDLORD_TRIPLE_WITH_PAIR", 1.2);
        model.strategyWeights.put("LANDLORD_PAIR", 1.0);
        model.strategyWeights.put("LANDLORD_SINGLE", 0.9);
        model.strategyWeights.put("LANDLORD_PASS", 0.7);

        // 初始化农民策略
        model.strategyWeights.put("FARMER_ROCKET", 1.4);
        model.strategyWeights.put("FARMER_BOMB", 1.3);
        model.strategyWeights.put("FARMER_STRAIGHT", 1.1);
        model.strategyWeights.put("FARMER_STRAIGHT_PAIR", 1.1);
        model.strategyWeights.put("FARMER_AIRPLANE", 1.2);
        model.strategyWeights.put("FARMER_TRIPLE_WITH_ONE", 1.0);
        model.strategyWeights.put("FARMER_TRIPLE_WITH_PAIR", 1.1);
        model.strategyWeights.put("FARMER_PAIR", 0.9);
        model.strategyWeights.put("FARMER_SINGLE", 0.8);
        model.strategyWeights.put("FARMER_PASS", 0.8);

        // 初始化平均剩余牌数
        model.strategyWeights.forEach((key, value) -> {
            model.averageRemainingCards.put(key, 10.0);  // 初始默认值
        });

        // 初始化叫分模式
        for (int i = 0; i < 100; i += 10) {
            String strengthKey = String.format("STRENGTH_%d", i);
            if (i >= 90) {
                model.bidPatterns.put(strengthKey, 3.0);
            } else if (i >= 70) {
                model.bidPatterns.put(strengthKey, 2.0);
            } else if (i >= 50) {
                model.bidPatterns.put(strengthKey, 1.0);
            } else {
                model.bidPatterns.put(strengthKey, 0.0);
            }
        }

        // 保存初始化的模型
        AIModelPersistence.saveModel(model);
        logger.info("基础策略权重初始化完成");
    }
} 